/**qmq
 * @file memAndSem.h
 * @author Mario Alvarez (mario.alvarezp@estudiante.uam.es) J. Angel Gonzalez (joseangel.gonzalezp@estudiante.uam.es)
 * @date 26-03-2011
 *
 * Fichero de cabecera de memAndSem.c
*/

#define _XOPEN_SOURCE				/*!< Define posix*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>

#ifndef MEM_AND_SEM_H
#define MEM_AND_SEM_H

#define SIGWAKEUP SIGUSR1
#define MEM_AND_SEM_OK 0
#define MEM_AND_SEM_ERR -1
#define MEM_AND_SEM_TIMEOUT 1

/**
* @brief Reserva un semaforo mutex.
*
* Reserva un semaforo de acceso unico, inicializandolo
* si es necesario.
*
* @param key Clave del semaforo a reservar.
* @return Id del semaforo reservado, -1 si error.
*/
int getMutex(int key);

/**
* @brief Libera un semaforo.
*
* Libera el semaforo mutex con id key.
*
* Nota: Actualmente, carece por completo de funcionalidad.
*
* @param id Id del semaforo a liberar.
* @return 0 si correcto, -1 si error.
*/
int freeMutex(int id);

/**
 * Solicita acceso a traves del semaforo numsem-esimo
 * del conjunto referenciado por id. En caso de no poder
 * atenderse la peticion, el proceso se bloquea hasta
 * poder acceder, manejando adecuadamente las sennales
 * entrantes y volviendo a bloquearse.
 *
 * @param id Id del conjunto de semaforos.
 * @param numsem Numero de semaforo dentro del array.
 * @return 0 si correcto, -1 si error.
*/
int down(int id, int numsem);

/**
 * Solicita acceso a traves del semaforo numsem-esimo
 * del conjunto referenciado por id. En caso de no poder
 * atenderse la peticion, el proceso se bloquea hasta
 * poder acceder.
 * Si, tras acabar la espera (bien por concesion de acceso
 * a recurso, bien por llegada de sennal) el flag apuntado
 * por bifurcar se halla a 1, el flujo se redirige a
 * alternativeFunction.
 *
 * @param id Id del conjunto de semaforos.
 * @param numsem Numero de semaforo dentro del array.
 * @param bifurcar Puntero a flag de control.
 * @param alternativeFunction Funcion de bifurcacion.
 * @return 0 si correcto, -1 si error.
*/
int downDireccionable(int id, int numsem, short *bifurcar, void (*alternativeFunction) (void));

/**
 * Concede acceso a traves del semaforo numsem-esimo
 * del conjunto referenciado por id.
 *
 * @param id Id del conjunto de semaforos.
 * @param numsem Numero de semaforo dentro del array.
 * @return 0 si correcto, -1 si error.
*/
int up(int id, int numsem);

/**
 * Duerme al proceso durante, a lo sumo, timeout nanosegundos,
 * a la espera de la recepcion de una sennal de wakeup.
 *
 * @param timeout Nanosegundos maximos de espera
 * @return 0 si correcto, -1 si error.
*/
int sleepUntilWakeup(long timeout);

/**
 * Despierta al proceso de PID pid de la espera
 * por sleepUntilWakeup.
 *
 * @param pid PID del proceso a despertar.
 * @return 0 si correcto, -1 si error.
*/
int wakeup(pid_t pid);

#endif
